#ifndef __UART_H__
#define __UART_H__

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "list.h"
#include "lock.h"
#include "wait.h"
#include "log.h"

#include <sys/prctl.h>

#define MAX_UART_MESSAGE_LENGTH 1024

struct uart_msg {
    uint8_t buffer[MAX_UART_MESSAGE_LENGTH];
    uint32_t length;
};

struct uart_config {
    char *dev;
    int speed;
    int databits;
    int stopbits;
    int parity;
    int stream;
};

struct uart;

enum UART_EVENT {
    UART_EVENT_NONE = 0,
    UART_EVENT_RECV,
    UART_EVENT_MAX,
};

typedef int32_t (*uart_event_notify)(struct uart*, int32_t, void*, void*);

struct uart_event_action {
    uart_event_notify notify;
    void* object;
    struct uart_event_action* next;
};

struct uart_operation {
    int32_t (*init)(struct uart*);
    int32_t (*release)(struct uart*);

    int32_t (*open)(struct uart*);
    int32_t (*close)(struct uart*);

    int32_t (*write)(struct uart*, uint8_t*, uint32_t);
    int32_t (*write_wait)(struct uart*, uint8_t*, uint32_t);

    int32_t (*register_notify)(struct uart*, int32_t, uart_event_notify notify, void*);
    int32_t (*unregister_notify)(struct uart*, int32_t, void*);
    int32_t (*trigger_notify)(struct uart*, int32_t, void*);
};

struct uart {
    struct list_head head;
    wait_t wait;
    lock_t lock;
    lock_t notify_lock;

    int running_flag;
    pthread_t pid;

    int opened;

    int fd;
    struct uart_config config;

    struct uart_operation* op;
    struct uart_event_action *paction[UART_EVENT_MAX];
};

int32_t create_init_uart(struct uart** puart);
void release_destroy_uart(struct uart* puart);
        
#endif